baselib.report(0x00, "TD4.5.4 beginning.")
-- 下面是初始化操作:
busilib.SetOrientation(1)             -- 设置USB的CC线,另一根则为Vconn线(这里设置CC1)
local VCC1 = 0
local VCC2 = 0
local i = 0                           -- 标志循环次数
local IntoStep3c = 0                  -- 标志进入第3.c步的次数
local tDRP = 50                       -- tDRP的值
local tDRP_dcSRC_DRP = 15             -- tDRP x dcSRC.DRP的值
--[[ 该脚本要执行9次,每次执行的参数如下:
1. tDRP = 50ms,  dcSRC.DRP = 30% [TD.4.5.4.C.1]
2. tDRP = 75ms,  dcSRC.DRP = 30% [TD.4.5.4.C.2]
3. tDRP = 100ms, dcSRP.DRP = 30% [TD.4.5.4.C.3]
4. tDRP = 50ms,  dcSRC.DRP = 50% [TD.4.5.4.C.4]
5. tDRP = 75ms,  dcSRC.DRP = 50% [TD.4.5.4.C.5]
6. tDRP = 100ms, dcSRC.DRP = 50% [TD.4.5.4.C.6]
7. tDRP = 50ms,  dcSRC.DRP = 70% [TD.4.5.4.C.7]
8. tDRP = 75ms,  dcSRC.DRP = 70% [TD.4.5.4.C.8]
9. tDRP = 100ms, dcSRC.DRP = 70% [TD.4.5.4.C.9]
]]

:: ScriptBegin ::
-- 第一步:确定tDRP和dcSRC.DRP的值
if i == 1 then
    tDRP = 75
    tDRP_dcSRC_DRP = 22
elseif i == 2 then
    tDRP = 100
    tDRP_dcSRC_DRP = 30
elseif i == 3 then
    tDRP = 50
    tDRP_dcSRC_DRP = 25
elseif i == 4 then
    tDRP = 75
    tDRP_dcSRC_DRP = 38
elseif i == 5 then
    tDRP = 100
    tDRP_dcSRC_DRP = 50
elseif i == 6 then
    tDRP = 50
    tDRP_dcSRC_DRP = 35
elseif i == 7 then
    tDRP = 75
    tDRP_dcSRC_DRP = 53
elseif i == 8 then
    tDRP = 100
    tDRP_dcSRC_DRP = 70
end

:: Script2Step ::
-- 第二步:CVS transitions to Unattached.SRC for (dcSRC.DRP x tDRP)
-- CVS转换到Unattached.SRC状态，持续时间为(dcSRC.DRP x tDRP)
busilib.setUsbRole(ROLE.Source)               
busilib.setUsbCcs(CCS.Unattached)
baselib.delay(tDRP_dcSRC_DRP)
-- 2.a步:CVS monitors CCs for Rd and transitions to AttachedWait.SRC if it is detected
-- CVS监控CC引脚上的Rd，如果检测到则转换到AttachedWait.SRC状态
VCC1 = busilib.GetADC(ADC.CC1, 4)
baselib.report(0x00, "CC1 is " .. tempVCC1 .. "mV")
if VCC1 < 200 then
    busilib.setUsbCcs(CCS.AttachedWait)
    -- 2.b步:If Rd is present for tCCDebounce: 1、CVS transitions to Attached.SRC   2、Skip to step 9
    -- 如果Rd存在时间达到tCCDebounce： 1、CVS转换到Attached.SRC状态。 2、跳到步骤9
    baselib.delay(200)                   -- 等待200ms(tCCDebounce)
    VCC1 = busilib.GetADC(ADC.CC1, 4)    -- 再次检测
    if VCC1 < 200 then
        busilib.setUsbCcs(CCS.Attached)
        goto Script9Step
    end
end

-- 第三步:CVS transitions to Unattached.SNK for tDRP – (dcSRC.DRP x tDRP)
-- CVS转换到Unattached.SNK状态，持续时间为tDRP - (dcSRC.DRP x tDRP)
busilib.setUsbCcs(CCS.Unattached)
busilib.setUsbRole(ROLE.Sink)
baselib.delay(tDRP - tDRP_dcSRC_DRP)
-- 3.a步:CVS monitors CCs for Rp and transitions to AttachedWait.SNK if it is detected
-- CVS监控CC引脚上的Rp，如果检测到则转换到AttachedWait.SNK状态
VCC1 = busilib.GetADC(ADC.CC1, 4)
baselib.report(0x00, "CC1 is " .. tempVCC1 .. "mV")
if VCC1 > 200 then
    busilib.setUsbCcs(CCS.AttachedWait)
    -- 3.b步:If Rp is present for tCCDebounce continue to step 4
    -- 如果Rp存在时间达到tCCDebounce：跳到步骤4
    baselib.delay(200)                   -- 等待200ms(tCCDebounce)
    VCC1 = busilib.GetADC(ADC.CC1, 4)    -- 再次检测
    if VCC1 > 200 then
        goto Script4Step
    else
        -- 3.c步:If the PUT has reached this step less than 5 times since step 1, transition to step 2
        -- 如果PUT在此步骤中执行的次数少于5次，则返回到步骤2
        IntoStep3c = IntoStep3c + 1
        if IntoStep3c < 5 then
            goto Script2Step
        end
    end
end

:: Script4Step ::
-- 第四步:CVS verifies PUT transitions to Attached.SRC:
-- 4.a步:PUT advertises VBUS capability over Rp [TD.4.5.4.V.1]  PUT通过Rp广告VBUS能力
-- 疑问：这一步应该有什么特殊操作吗，因为第3步已经验证Rp了

-- 4.b步:PUT sources VBUS within tCCDebounce + tVBUSOn [TD.4.5.4.V.2]  PUT在tCCDebounce + tVBUSOn时间内提供VBUS
baselib.delay(475)               -- tCCDebounce:200ms+tVBUSON:275ms
if cstmlib.VBusVerified(1) then 
    baselib.report(0x00, "TD4.5.4.V.2 pass.")
else
    baselib.report(0x00, "TD4.5.4.V.2 fail.")
end
-- 第4.c步:If PUT supports USB PD:PUT stabilizes VBUS before initiating USB PD communications [TD.4.5.4.V.3]
-- 如果PUT支持USB PD，PUT在启动USB PD通信之前稳定VBUS
if PUT_supports_PD then
    local VBus = busilib.GetADC(ADC.VBUS, 4)
    baselib.report(0x00, "VBus is " .. VBus .. "mV.")
    if VBus > 3670 then 
        baselib.report(0x00, "TD4.5.4.V.3 pass.")
    else
        baselib.report(0x00, "TD4.5.4.V.3 fail.")
    end
end

-- 第五步:CVS transitions to Disabled
busilib.setUsbCcs(CCS.Disabled)
-- 第六步:CVS verifies that PUT transitions to Unattached.SNK within tSRCDisconnect  PUT在tSRCDisconnect时间内过渡到Unattached.SNK状态
-- 第6.a步:Vbus reaches vSave0V before tVBUSOFF expires [TD.4.5.4.V.5]               VBUS在tVBUSOFF时间内降到vSafe0V
local VBUS = busilib.GetADC(ADC.VBUS, 4)          
baselib.report(0x00, "VBUS is " .. VBUS .. "mV.")
if VBUS < 0.8 then
    baselib.report(0x00, "TD.4.5.4.V.5 pass.")
else
    baselib.report(0x00, "TD.4.5.4.V.5 fail.")
end
-- 第6.b步:PUT ceases PD communications [TD.4.5.4.V.6]                                PUT停止PD通信
-- 不知道怎么检查，先空着
-- 第6.c步:PUT terminates CC with Rd [TD.4.5.4.V.7]   If PUT is a PUT_R, it terminates both CCs with Rd
-- PUT在CC线上提供Rd（如果是PUT_R，则两个CC线都提供Rd）
VCC1 = busilib.GetADC(ADC.CC1, 4)
VCC2 = busilib.GetADC(ADC.CC2, 4)
baselib.report(0x00, "CC1 is " .. VCC1 .. "mV, and CC2 is " .. VCC2 .. "mV.")
if PUT_R then
    if VCC1 < 200 and VCC2 < 200 then
        baselib.report(0x00, "TD4.5.4.V.7 pass.")
    else
        baselib.report(0x00, "TD4.5.4.V.7 fail.")
    end
else
    if VCC1 < 200 then
        baselib.report(0x00, "TD4.5.4.V.7 pass.")
    else
        baselib.report(0x00, "TD4.5.4.V.7 fail.")
    end
end
-- 第七步:CVS transitions to Unattached.SRC,For a PUT_R, one CC is terminated with Ra
-- CVS过渡到Unattached.SRC状态：对于PUT_R，一个CC线提供Ra
busilib.setUsbCcs(CCS.Unattached)
busilib.setUsbRole(ROLE.Source)
if PUT_R then
    busilib.SetSwitchState(SW.CC2_RA, 1)       -- 将CC2_RA开关打开
end
-- 第八步:CVS transitions to Attached.SRC
busilib.setUsbCcs(CCS.Attached)

:: Script9Step ::
-- 第九步:CVS verifies PUT transitions to Attached.SNK:      验证PUT转换到Attached.SNK状态
--[[9.a步:监测VBUS电流,for 500ms,电流数值可以是20ms内的平均值,判别不超过500mA(对应tester宣传的500mA供电能力)         
(原文:PUT sinks current according to CVS advertisement [TD.4.5.4.V.8]) ]]
--[[busilib.newTrans4ad(debounce,adc_channel,thresholds)功能:新建一个状态翻译器。
参数:debounce:采样并去抖次数。  adc_channel:要翻译的 ADC 通道。  thresholds:阈值列表,状态数量为阈值数量加一,长度最大为 254。
返回值:trans_id:新建的状态翻译器 ID。 ]]
local trans1 = busilib.newTrans4ad(4, ADC.CC2, {2750})
--这里对上面的trans1的状态1监控,6.d的这两行代码写前面是因为需要提前启动监控器
local monitor3 = busilib.newMonitor(TMD.CHECK_POINT, trans1, {1}, {0}, {0})
--[[busilib.waitCondition4ad(adc_channel,debonce,lower_limit,upper_limit,times,timeout) 功能:阻塞脚本,等待某条件达成。
参数:adc_channel:要监控的 ADC 通道。  debounce:采样并去抖次数。  lower_limit:目标条件值下限。  upper_limit:目标条件值上限。  times:目标需要的达成次数。  timeout:超时时间,单位为毫秒。
返回值:返回 LuaOk 表示在超时时间内达成目标条件,返回 LuaTimeout 表示超时。 ]]
if busilib.waitCondition4ad(ADC.VBUS_I, 20, 500, 5000, 1, 500) == LuaOk then
    baselib.report(0x00, "TD.4.5.4.V.8 fail.")         --出现LuaOK说明有大于500mA的电流出现了一次,检查点fail
else
    baselib.report(0x00, "TD.4.5.4.V.8 pass.")
end
-- 9.b步:If PUT supports PD, CVS and PUT establish a PD contract. [TD.4.5.4.V.9]
-- 如果PUT支持PD，CVS和PUT协商PD协议
if USB_PD_Support then
    baselib.report(0x00, "Begin power negotiation.")
    tcpclib.SetPermission(1, 2)
    PN_result = tcpclib.PresetPowerNegotiation(1, 500)  --timeout is 500ms
    if PN_result == LuaOk then
        baselib.report(0x00, "TD4.5.4.V.9 pass.")
    else
        if PN_result == LuaTimeout then
            baselib.report(0x00, "Power negotiation timeout.")
        else
            baselib.report(0x00, "Unsupported power request received.")
        end
        baselib.report(0x00, "TD4.5.4.V.9 fail.")
    end
end
-- 9.d步:Else if PUT supports USB 2.0 UFP:PUT starts data communications on its D+/D- pair. [TD.4.5.4.V.11]
-- 不会写,先空着
-- 9.e步:检查CC2电压不超过2.75V    (原文:For a PUT_R, VCONN is not supplied [TD.4.5.4.V.12] )
if busilib.getMonitorResult(monitor3) ~= 1 then        --出现1就是超过2750mV,否则检查点pass
    baselib.report(0x00, "TD.4.5.4.V.12 pass.")
else
    baselib.report(0x00, "TD.4.5.4.V.12 fail.")
end
--删除监控器
busilib.deleteMonitor(monitor3)
busilib.deleteTrans(trans1)

-- 第十步:CVS transmits Discover ID PD messaging for 200ms
-- CVS发送Discover ID PD消息200ms
-- 之后会包装成函数,这里先空着
-- 第十一步:CVS verifies PUT:1、If USB_PD_Support is YES:Responds with valid GoodCRC messages. [TD.4.5.4.V.13]
if USB_PD_Support then
    -- 不会写,先空着
end
-- 2、If Responds_To_Discov_SOP is YES:Transmits valid Responder ACK messages. [TD.4.5.4.V.14]
if Responds_To_Discov_SOP then
    -- 不会写,先空着
end
-- 第十二步:CVS programs Vbus source to meet 3.7V at the PUT connector     CVS设置VBUS源电压为3.7V
-- 对应阻值是？
-- 第十三步:CVS verifies PUT remains in Attached.SNK       验证PUT保持在Attached.SNK状态
-- 13.a步:PUT maintains Rd on its CC [TD.4.5.4.V.15]       PUT在CC线上保持Rd
VCC1 = busilib.GetADC(ADC.CC1, 4)
if VCC1 < 200 then
    baselib.report(0x00, "TD4.5.4.V.15 pass.")
else
    baselib.report(0x00, "TD4.5.4.V.15 fail.")
end
-- 13.b步:For a PUT that supports USB 3.2 or USB 2.0 UFP, the data signaling is maintained. [TD.4.5.4.V.16]
-- 对于支持USB 3.2或USB 2.0 UFP的PUT，保持数据信号
-- 不会写,先空着

-- 第十四步:CVS removes Rps. CVS USB 2.0 and USB 3.1 signaling behaves as a DFP in Attached.SRC as long as PUT is in Attached.SNK.
-- CVS移除Rp。只要PUT保持在Attached.SNK状态，CVS的USB 2.0和USB 3.1信号行为就像DFP一样。
-- 不会写,先空着

-- 第十五步:CVS decreases Vbus voltage by 0.1V     CVS降低VBUS电压0.1V
-- 对应阻值是？
while(true)
do
    -- 15.a步:Wait 100ms
    baselib.delay(100) 
    -- 15.b步:If PUT removes Rd or Vbus source voltage is below 800mV, continue to step 16
    -- 如果PUT移除Rd或VBUS源电压低于800mV，继续到步骤16,即跳出循环
    if ????? then
        break
    end
    -- 15.c步:CVS verifies PUT maintained Attached.SNK    验证PUT保持在Attached.SNK状态
    -- 1、PUT maintains Rd on its CC [TD.4.5.4.V.17]       PUT在CC线上保持Rd
    VCC1 = busilib.GetADC(ADC.CC1, 4)
    if VCC1 < 200 then
        baselib.report(0x00, "TD4.5.4.V.17 pass.")
    else
        baselib.report(0x00, "TD4.5.4.V.17 fail.")
    end
    -- 2、For a PUT that supports USB 3.2 or USB 2.0 UFP, the data signaling is maintained. [TD.4.5.4.V.18]
    -- 对于支持USB 3.2或USB 2.0 UFP的PUT，保持数据信号
    -- 不会写,先空着
    -- 3、PUT does not source Vbus [TD.4.5.4.V.19]
    VBUS = busilib.GetADC(ADC.VBUS, 4)         
    if VBUS > 0.8 then
        baselib.report(0x00, "TD.4.5.4.V.19 fail.")
    else
        baselib.report(0x00, "TD.4.5.4.V.19 pass.")
    end
    -- 15.d:继续循环
end
-- 第十六步:CVS applies Rd
busilib.SetSwitchState(SW.CC1_RD, 1)       --打开CC1上的Rd
-- 第十七步:CVS verifies PUT transitions to AttachWait.SRC within tOnePortToggleConnect
-- 验证PUT在tOnePortToggleConnect时间内过转换到AttachWait.SRC状态
-- 17.a步:PUT applies and maintains Rp on its CC [TD.4.5.4.V.20]  For a PUT_R, Rp is applied on both CCs
VCC1 = busilib.GetADC(ADC.CC1, 4)
VCC2 = busilib.GetADC(ADC.CC2, 4)
baselib.report(0x00, "CC1 is " .. VCC1 .. "mV, and CC2 is " .. VCC2 .. "mV.")
if PUT_R then
    if VCC1 > 200 and VCC2 > 200 then
        baselib.report(0x00, "TD4.5.4.V.20 pass.")
    else
        baselib.report(0x00, "TD4.5.4.V.20 fail.")
    end
else
    if VCC1 > 200 then
        baselib.report(0x00, "TD4.5.4.V.20 pass.")
    else
        baselib.report(0x00, "TD4.5.4.V.20 fail.")
    end
end
-- 17.b:PUT does not source Vbus [TD.4.5.4.V.21]
VBUS = busilib.GetADC(ADC.VBUS, 4)         
if VBUS > 0.8 then
    baselib.report(0x00, "TD.4.5.4.V.21 fail.")
else
    baselib.report(0x00, "TD.4.5.4.V.21 pass.")
end
-- 17.c:All data signaling ceases [TD.4.5.4.V.22]    所有数据信号停止
-- 不会写,先空着

-- 第十八步:If Vbus is at or below 800 mV, continue to step 20    如果VBUS电压低于或等于800mV，继续到步骤20
VBUS = busilib.GetADC(ADC.VBUS, 4)  
if VBUS <= 0.8 then
    goto Script20Step
end
-- 第十九步:CVS verifies PUT remains in AttachWait.SRC for 500ms [TD.4.5.4.V.23]
-- 验证PUT在AttachWait.SRC状态下保持500ms
local trans1 = busilib.newTrans4ad(8, ADC.CC1, {250})
local monitor1 = busilib.newMonitor(TMD.CHECK_POINT, trans1, {0}, {0}, {0})
if busilib.waitCondition4ad(ADC.VBUS, 4, 0, 3670, 1, 500) == LuaOk then
    baselib.report(0x00, "TD4.5.4.V.23 fail.")
else
    if busilib.getMonitorResult(monitor1) == 1 then
        baselib.report(0x00, "TD4.5.4.V.23 fail.")
    else
        baselib.report(0x00, "TD4.5.4.V.23 pass.")
    end
end

:: Script20Step ::
-- 第二十步:CVS removes Vbus source

-- 第二十一步:CVS verifies that PUT sources Vbus after Vbus is in vSafe0V, and before tVbusON expires. [TD.4.5.4.V.24]
-- 验证PUT在VBUS降到vSafe0V后且在tVbusON时间内提供VBUS
-- 第二十二步:CVS transitions to Disabled
busilib.setUsbCcs(CCS.Disabled)
-- 第二十三步:CVS continues to Step 1 with the next Condition listed above
if i < 9 then
    i = i + 1
    goto ScriptBegin
end

baselib.report(0x00, "Demo is done here.")
baselib.report(0x07, "\x04")